﻿using System;
using System.Windows;
using System.Windows.Input;
using MaxAlarm.Core.Items;
using MaxAlarm.Core.Settings;
using MaxAlarm.Pages;
using MaxAlarm.Windows;
using Microsoft.Win32;

namespace MaxAlarm.ViewModels
{
    public class SettingsPageViewModel : FrameworkElement
    {
        #region Commands

        private static readonly ICommand _saveCommand = new RoutedUICommand("Save", "SaveCommand", typeof(SettingsPageViewModel));
        private static readonly ICommand _cancelCommand = new RoutedUICommand("Cancel", "CancelCommand", typeof(SettingsPageViewModel));

        public static ICommand SaveCommand
        {
            get { return _saveCommand; }
        }

        public static ICommand CancelCommand
        {
            get { return _cancelCommand; }
        }


        private static readonly ICommand _saveNewItemCommand = new RoutedUICommand("SaveNewItem", "SaveNewItemCommand", typeof(SettingsPageViewModel));
        private static readonly ICommand _cancelNewItemCommand = new RoutedUICommand("CancelNewItem", "CancelNewItemCommand", typeof(SettingsPageViewModel));

        public static ICommand SaveNewItemCommand
        {
            get { return _saveNewItemCommand; }
        }

        public static ICommand CancelNewItemCommand
        {
            get { return _cancelNewItemCommand; }
        }


        private static readonly ICommand _selectFileCommand = new RoutedUICommand("SelectFile", "SelectFileCommand", typeof(SettingsPageViewModel));
        private static readonly ICommand _clearLoginsCommand = new RoutedUICommand("ClearLogins", "ClearLoginsCommand", typeof(SettingsPageViewModel));

        public static ICommand SelectFileCommand
        {
            get { return _selectFileCommand; }
        }

        public static ICommand ClearLoginsCommand
        {
            get { return _clearLoginsCommand; }
        }


        private static readonly ICommand _removeItemCommand = new RoutedUICommand("RemoveItem", "RemoveItemCommand", typeof(SettingsPageViewModel));

        public static ICommand RemoveItemCommand
        {
            get { return _removeItemCommand; }
        }

        private static readonly ICommand _editItemCommand = new RoutedUICommand("EditItem", "EditItemCommand", typeof(SettingsPageViewModel));

        public static ICommand EditItemCommand
        {
            get { return _editItemCommand; }
        }

        private static readonly ICommand _addItemCommand = new RoutedUICommand("AddItem", "AddItemCommand", typeof(SettingsPageViewModel));

        public static ICommand AddItemCommand
        {
            get { return _addItemCommand; }
        }

        #endregion

        #region Properties

        public static readonly DependencyProperty SettingsProperty =
            DependencyProperty.Register("Settings", typeof (MaxAlarmSettings), typeof (SettingsPageViewModel), new PropertyMetadata(null));

        public MaxAlarmSettings Settings
        {
            get { return (MaxAlarmSettings) GetValue(SettingsProperty); }
            set { SetValue(SettingsProperty, value); }
        }

        public static readonly DependencyProperty PageManagerProperty =
            DependencyProperty.Register("PageManager", typeof (PageManager), typeof (SettingsPageViewModel), new PropertyMetadata(null));

        public PageManager PageManager
        {
            get { return (PageManager) GetValue(PageManagerProperty); }
            set { SetValue(PageManagerProperty, value); }
        }

        public static readonly DependencyProperty IsAddPanelVisibleProperty =
            DependencyProperty.Register("IsAddPanelVisible", typeof(bool), typeof(SettingsPageViewModel), new PropertyMetadata(false, AddPanelChanged));

        private static void AddPanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var page = (SettingsPageViewModel)d;
            page.TempItem = new AlarmSettingsItem();
        }

        public bool IsAddPanelVisible
        {
            get { return (bool) GetValue(IsAddPanelVisibleProperty); }
            set { SetValue(IsAddPanelVisibleProperty, value); }
        }



        public static readonly DependencyProperty IsEditPanelVisibleProperty =
            DependencyProperty.Register("IsEditPanelVisible", typeof(bool), typeof(SettingsPageViewModel), new PropertyMetadata(false, EditPanelChanged));

        public bool IsEditPanelVisible
        {
            get { return (bool)GetValue(IsEditPanelVisibleProperty); }
            set { SetValue(IsEditPanelVisibleProperty, value); }
        }

        public static readonly DependencyProperty TempItemProperty =
            DependencyProperty.Register("TempItem", typeof (AlarmSettingsItem), typeof (SettingsPageViewModel), new PropertyMetadata(null));

        private static void EditPanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!((bool)e.NewValue))
                return;

            var vm = (SettingsPageViewModel)d;
            var item = vm.SelectedAlarm;

            if (item == null)
                return;

            vm.TempItem = (AlarmSettingsItem)item.Clone();
        }

        public AlarmSettingsItem TempItem
        {
            get { return (AlarmSettingsItem) GetValue(TempItemProperty); }
            set { SetValue(TempItemProperty, value); }
        }

        public static readonly DependencyProperty HasErrorProperty =
            DependencyProperty.Register("HasError", typeof (bool), typeof (SettingsPageViewModel), new PropertyMetadata(false));

        public bool HasError
        {
            get { return (bool) GetValue(HasErrorProperty); }
            set { SetValue(HasErrorProperty, value); }
        }

        public static readonly DependencyProperty ErrorTextProperty =
            DependencyProperty.Register("ErrorText", typeof (string), typeof (SettingsPageViewModel), new PropertyMetadata(string.Empty));

        public string ErrorText
        {
            get { return (string) GetValue(ErrorTextProperty); }
            set { SetValue(ErrorTextProperty, value); }
        }

        public static readonly DependencyProperty SelectedAlarmProperty =
            DependencyProperty.Register("SelectedAlarm", typeof (AlarmSettingsItem), typeof (SettingsPageViewModel), new PropertyMetadata(default(AlarmSettingsItem)));

        public AlarmSettingsItem SelectedAlarm
        {
            get { return (AlarmSettingsItem) GetValue(SelectedAlarmProperty); }
            set { SetValue(SelectedAlarmProperty, value); }
        }

        #endregion

        #region Ctors

        public SettingsPageViewModel()
        {
            Settings = (MaxAlarmSettings)SettingsManager.Instance.Settings.Clone();
        }

        static SettingsPageViewModel()
        {
            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(SaveCommand, SaveExecuted));
            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(CancelCommand, CancelExecuted));

            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(SelectFileCommand, SelectFileExecuted));
            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(ClearLoginsCommand, ClearLoginsExecuted));

            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(CancelNewItemCommand, CancelNewItemExecuted));
            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(SaveNewItemCommand, SaveNewItemExecuted));


            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(RemoveItemCommand, RemoveItemExecuted, RemoveCanExecuted));
            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(EditItemCommand, EditItemExecuted, EditCanExecuted));
            CommandManager.RegisterClassCommandBinding(typeof(SettingsPage), new CommandBinding(AddItemCommand, AddItemExecuted, AddItemCanExecuted));
        }

        #endregion

        #region Command executors

        private static void AddItemCanExecuted(object sender, CanExecuteRoutedEventArgs e)
        {
            var page = (SettingsPage)sender;
            e.CanExecute = page.IsInitialized && !page.ViewModel.IsEditPanelVisible;
        }

        private static void AddItemExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            
        }

        private static void EditCanExecuted(object sender, CanExecuteRoutedEventArgs e)
        {
            var page = (SettingsPage)sender;
            e.CanExecute = page.IsInitialized && page.ViewModel.SelectedAlarm != null && !page.ViewModel.IsEditPanelVisible && !page.ViewModel.IsAddPanelVisible;
        }

        private static void EditItemExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            
        }

        private static void RemoveCanExecuted(object sender, CanExecuteRoutedEventArgs e)
        {
            var page = (SettingsPage)sender;
            e.CanExecute = page.IsInitialized && page.ViewModel.SelectedAlarm != null && !page.ViewModel.IsEditPanelVisible && !page.ViewModel.IsAddPanelVisible;
        }

        private static void RemoveItemExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var page = (SettingsPage)sender;
            var item = page.ViewModel.SelectedAlarm;

            if (item == null)
                return;

            page.ViewModel.Settings.AlarmSettings.Items.Remove(item);
        }

        private static void SaveNewItemExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var page = (SettingsPage)sender;

            try
            {
                page.ViewModel.Settings.AlarmSettings.AddNew(page.ViewModel.TempItem);
                page.ViewModel.IsAddPanelVisible = false;
                page.ViewModel.IsEditPanelVisible = false;
                page.ViewModel.HasError = false;
            }
            catch (Exception ex)
            {
                page.ViewModel.HasError = true;
                page.ViewModel.ErrorText = ex.Message;
            }
           
        }

        private static void CancelNewItemExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var page = (SettingsPage) sender;
            page.ViewModel.IsAddPanelVisible = false;
            page.ViewModel.HasError = false;
            page.ViewModel.IsEditPanelVisible = false;
        }

        private static void ClearLoginsExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var dialog = new MaxMessageBox("Clear logins history?", "Do you want clear logins history?",
                                           MessageLevel.Question, MessageBoxButton.YesNo,
                                           Application.Current.MainWindow);
            dialog.ShowDialog();


            if (dialog.DialogResult != DialogResult.Yes)
                return;


            var page = (SettingsPage)sender;
            page.ViewModel.Settings.AccountsSettings.Accounts.Clear();
        }

        private static void SelectFileExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var page = (SettingsPage)sender;
            var dialog = new OpenFileDialog {Filter = "Sound Files  (*.wav; *.mp3)|*.wav; *.mp3"};

            if(dialog.ShowDialog(Application.Current.MainWindow) == true)
            {
                page.PathBox.Text = dialog.FileName;
            }
        }

        private static void CancelExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var page = (SettingsPage) sender;
            page.ViewModel.Settings = (MaxAlarmSettings)SettingsManager.Instance.Settings.Clone();
            page.ViewModel.PageManager.GoToPrevoiusPage();
        }

        private static void SaveExecuted(object sender, ExecutedRoutedEventArgs executedRoutedEventArgs)
        {
            var page = (SettingsPage) sender;
            SettingsManager.Instance.Settings = page.ViewModel.Settings;
            SettingsManager.Instance.SaveSetting();
            SettingsManager.Instance.Initialize();
            page.ViewModel.PageManager.GoToPrevoiusPage();
        }

        #endregion
    }
}
